<template>
  <view class="chatInterface" @click="handlePageClick">
    <view class="scroll-view">
      <view class="message-list">
        <view v-for="(message,index) in history.messages" :key="message.messageId">
          <view class="time-lag">
            {{ renderMessageDate(message, index) }}
          </view>
          <view class="message-item">
            <view v-if="message.content_type === 'CS_ACCEPT'" class="accept-message">
              {{ message.senderData.name }}已接入
            </view>
            <view v-else-if="message.content_type === 'CS_END'" class="accept-message">
              {{ message.senderData.name }}已结束会话
            </view>
            <div v-else-if="message.content_type === 'CS_TRANSFER'" class="accept-message">
              {{ message.payload.transferTo.data.name }}已接入
            </div>
            <view v-else :class="{'self' : message.user_id ===  currentCustomer.id}" class="message-item-content">
              <view class="avatar">
                <image :src="message.user_id === currentCustomer.id? currentCustomer.image_url : shop.image_url"></image>
              </view>
              <view class="content">
                <view v-if="message.user_id !== currentCustomer.id" class="staff-name" style="margin-bottom: 10rpx;">
                </view>
                <view class="message-payload">
                  <b v-if="message.status === 'sending'" class="pending"></b>
                  <b v-if="message.status === 'fail'" class="send-fail"></b>
                  <view v-if="message.content_type === 'text'" v-html="renderTextMessage(message)"></view>
                  <image v-if="message.content_type === 'image'"
                     :data-url="message.content"
                     :src="baseUrl+message.content"
                     class="image-content"
                     mode="heightFix"
                     @click="showImageFullScreen"
                  ></image>
                </view>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>
    <view class="action-box" :style="{ bottom: keyboardHeight + 'px' }">
      <view class="action-top">
        <view @click="switchAudioKeyboard">
          <image class="more" v-if="audio.visible" src="/static/images/jianpan.png"></image>
        </view>
        <view v-if="audio.visible" class="record-input" @click="onRecordStart" @touchend="onRecordEnd" @touchstart="onRecordStart">
          {{ audio.recording ? '松开发送' : '按住录音' }}
        </view>
        <input v-else v-model="text" @confirm="sendTextMessage" @focus="onInputFocus" class="consult-input" maxlength="700" placeholder="发送消息" type="text" :adjust-position="shouldAdjustPosition" />
        <view @click="switchEmojiKeyboard">
        </view>
        <view>
          <image @click.stop="showOtherTypesMessagePanel()" class="more" src="/static/images/more.png"/>
        </view>
        <view v-if="text" class="send-btn-box">
          <text class="btn" @click="sendTextMessage()">发送</text>
        </view>
      </view>
      <view v-if="otherTypesMessagePanelVisible" class="action-bottom" @click.stop="">
        <view class="more-icon">
          <image @click="sendImageMessage()" class="operation-icon" src="/static/images/picture.png"></image>
          <view class="operation-title">图片</view>
        </view>
      </view>
    </view>
    <view v-if="audio.recording" class="record-loading"></view>
  </view>
</template>

<script>
  import restApi from '../lib/restapi';
  import { formatDate } from '../lib/utils';
  import EmojiDecoder from '../lib/EmojiDecoder';
  import { config } from '../lib/config';
  const recorderManager = uni.getRecorderManager();
  const IMAGE_MAX_WIDTH = 200;
  const IMAGE_MAX_HEIGHT = 150;
  export default {
    data() {
      const fakeShop = {
        id: 'shop_001',
        name: '旗舰店客服',
        image_url: 'https://randomuser.me/api/portraits/women/44.jpg'
      };
      const fakeOrders = [];
      const fakeMessages = [];

      return {
        baseUrl: config.baseUrl,
        currentCustomer: uni.getStorageSync('user'),
        shop: fakeShop,
        to: {},
        text: '',
        keyboardHeight: 0,
        otherTypesMessagePanelVisible: false,
        orderList: {
          orders: fakeOrders,
          visible: false
        },
        history: {
          messages: fakeMessages,
          allLoaded: false,
          loading: false
        },
        audio: {
          startTime: null,
          recording: false,
          visible: false
        },
        audioPlayer: {
          innerAudioContext: null,
          playingMessage: null,
        },
        videoPlayer: {
          visible: false,
          url: '',
          context: null
        },
        ws: {
          timer: null,
          heartbeatTimer: null,
          reconnectTimer: null,
          reconnectCount: 0,
          maxReconnectCount: 9999,
          isConnected: false
        }
      }
    },
    computed: {
      shouldAdjustPosition() {
        return this.history.messages.length > 5;
      }
    },
    onLoad(options) {
      uni.showLoading({
        title: '加载中...'
      });
      // if (!uni.getStorageSync('token')) {
      //   uni.reLaunch({
      //     url: '/pages/login'
      //   })
      //   return
      // }
      uni.request({
        url: `${config.baseUrl}/api/v1/getBaseInfo`,
        method: 'GET',
        header: {
          'Authorization': uni.getStorageSync('token')
        }
      }).then(res => {
        this.shop.image_url = config.baseUrl + res[1].data.result.CustomerServiceImage;
        uni.hideLoading();
      }).catch(err => {
        console.log(err);
        uni.hideLoading();
      })  
      this.connect();
      
      uni.onKeyboardHeightChange((res) => {
        if (this.history.messages.length <= 5) {
          this.keyboardHeight = res.height;
        } else {
          this.keyboardHeight = 0;
        }
        
        if (res.height > 0) {
          setTimeout(() => {
            this.scrollToBottom();
          }, 100);
        }
      });

      this.currentCustomer = uni.getStorageSync('user') 
    },
    onReady() {
      uni.setNavigationBarTitle({
        title: '众盈瑞达'
      });
    },
    onShow() {
      uni.showLoading({
        title: '恢复聊天中'
      });
      
      this.checkAndReconnectWebSocket();
      this.loadHistoryMessage(true, 1);
    },
    beforeDestroy() {
      if (this.ws.heartbeatTimer) {
        clearInterval(this.ws.heartbeatTimer);
      }
      if (this.ws.reconnectTimer) {
        clearTimeout(this.ws.reconnectTimer);
      }
      uni.closeSocket();
    },
    methods: {
      connect() {
        uni.connectSocket({
          header: {
            'Authorization': uni.getStorageSync('token')
          },
          url: config.webkitURL,
          success: () => {
            console.log('WebSocket连接成功');
          },
          fail: (err) => {
            console.error('WebSocket连接失败:', err);
            this.reconnect();
          }
        });

        uni.onSocketOpen(() => {
          console.log('WebSocket连接已打开');
          this.ws.reconnectCount = 0;
          this.ws.isConnected = true;
          this.startHeartbeat();
        });

        uni.onSocketMessage((res) => {
          try {
            const data = JSON.parse(res.data);
            if (data.user_id == this.currentCustomer.id) {
              return
            }

            if (res.data === 'pong') {
              console.log('收到心跳响应');
              return;
            }

            if (data.content_type && data.content) {
              const message = {
                messageId: 'msg' + Date.now(),
                content_type: data.content_type,
                content: data.content,
                create_time: Date.now(),
                type: data.content_type,
                user_id: data.user_id || 'system',
                senderData: {
                  name: data.sender_name || '系统'
                }
              };
              this.history.messages.push(message);
              this.scrollToBottom();
            }
          } catch (err) {
            console.error('解析WebSocket消息失败:', err, '原始数据:', res.data);
          }
        });

        uni.onSocketError((res) => {
          console.error('WebSocket连接打开失败，请检查！', res);
          this.ws.isConnected = false;
          this.reconnect();
        });

        uni.onSocketClose((res) => {
          console.log('WebSocket已关闭！');
          this.ws.isConnected = false;
          this.reconnect();
        });
      },

      startHeartbeat() {
        if (this.ws.heartbeatTimer) {
          clearInterval(this.ws.heartbeatTimer);
        }
        this.ws.heartbeatTimer = setInterval(() => {
          this.sendHeartbeat();
        }, 30000);
      },

      sendHeartbeat() {
        uni.sendSocketMessage({
          data: 'ping',
          success: () => {
            console.log('心跳发送成功');
          },
          fail: (err) => {
            console.error('心跳发送失败:', err);
            this.reconnect();
          }
        });
      },

      reconnect() {
        if (this.ws.reconnectCount >= this.ws.maxReconnectCount) {
          console.log('重连次数超过最大限制，停止重连');
          return;
        }

        if (this.ws.reconnectTimer) {
          clearTimeout(this.ws.reconnectTimer);
        }

        this.ws.reconnectTimer = setTimeout(() => {
          console.log(`第${this.ws.reconnectCount + 1}次重连`);
          this.ws.reconnectCount++;
          this.connect();
        }, 3000);
      },

      getImageHeight(width, height) {
        if (width < IMAGE_MAX_WIDTH && height < IMAGE_MAX_HEIGHT) {
          return height * 2;
        } else if (width > height) {
          return (IMAGE_MAX_WIDTH / width * height) * 2;
        } else if (width === height || width < height) {
          return IMAGE_MAX_HEIGHT * 2;
        }
      },
      
      renderMessageDate(message, index) {
        if (index === 0) {
          return formatDate(message.create_time)
        } else {
          if (message.create_time - this.history.messages[index - 1].create_time > 5 * 60 * 1000) {
            return formatDate(message.create_time)
          }
        }
        return '';
      },
      
      renderTextMessage(message) {
        return '<span class="text-content">' + message.content + '</span>'
      },
      
      switchEmojiKeyboard() {
        this.otherTypesMessagePanelVisible = false;
      },
      
      onInputFocus() {
        this.otherTypesMessagePanelVisible = false;
      },
      
      showOtherTypesMessagePanel() {
        this.otherTypesMessagePanelVisible = !this.otherTypesMessagePanelVisible;
      },
      
      sendTextMessage() {
            if (!uni.getStorageSync('token')) {
            uni.showModal({
              title: '提示',
              content: '请先登录',
              success: (res) => {
                if (res.confirm) {
                  uni.reLaunch({
                url: '/pages/login'
              })
                }
              }
            })
            return
      }
        if (this.text.trim() !== '') {
          const now = Date.now();
          const message = {
            messageId: 'msg' + now,
            type: 'text',
            senderId: this.currentCustomer.user_id,
            senderData: { name: this.currentCustomer.name },
            timestamp: now,
            payload: { text: this.text },
            status: 'sending',
            content: this.text,
            create_time: now,
            content_type: 'text',
            user_id: this.currentCustomer.id,
          };
          this.history.messages.push(message);
          this.scrollToBottom();

          const wsMessage = {
            content_type: 'text',
            content: this.text
          };
          
          uni.sendSocketMessage({
            data: JSON.stringify(wsMessage),
            success: () => {
              console.log('消息发送成功');
              const messageIndex = this.history.messages.findIndex(msg => msg.messageId === message.messageId);
              if (messageIndex !== -1) {
                this.history.messages[messageIndex].status = 'success';
              }
            },
            fail: (err) => {
              console.error('消息发送失败:', err);
              const messageIndex = this.history.messages.findIndex(msg => msg.messageId === message.messageId);
              if (messageIndex !== -1) {
                this.history.messages[messageIndex].status = 'fail';
              }
            }
          });
          this.text = '';
        }
      },
      
      scrollToBottom() {
        this.$nextTick(() => {
          uni.pageScrollTo({
            scrollTop: 2000000,
            duration: 0
          });
        });
      },
      
      loadHistoryMessage(scrollToBottom, page) {
        uni.request({
          url: `${config.baseUrl}/api/v1/getChatRecord`,
          method: 'POST',
          header: {
            'Authorization': uni.getStorageSync('token')
          },
          data: {
            page: page,
            pageSize: 9999
          }
        }).then(res => {
          console.log(res);
          uni.hideLoading();
          this.history.loading = false;
          if(res[1].data.result.content.length == 0){
            res[1].data.result.content.push({
              content: "很高兴为您服务，请问有什么问题要咨询",
              content_type: "text",
              create_time: Date.now(),
              deleted: "1",
              enable: "1",
              id: Date.now(),
              session_id: 10005,
              state: 0,
              strId: Date.now().toString(),
              update_time: Date.now(),
              user_id: 1,
              user_type: 0,
            })
          }
          this.history.messages = res[1].data.result.content;
          this.scrollToBottom();
        }).catch(err => {
          console.log(err);
          uni.hideLoading();
          // 获取历史消息失败时也添加默认消息
          this.history.messages = [{
            content: "很高兴为您服务，请问有什么问题要咨询",
            content_type: "text",
            create_time: Date.now(),
            deleted: "1",
            enable: "1",
            id: Date.now(),
            session_id: 10005,
            state: 0,
            strId: Date.now().toString(),
            update_time: Date.now(),
            user_id: 1,
            user_type: 0,
          }];
          this.scrollToBottom();
        })
      },
      
      switchAudioKeyboard() {
        this.audio.visible = !this.audio.visible;
      },
      
      onRecordStart() {
        try {
          recorderManager.start();
        } catch (e) {
          uni.showModal({
            title: '录音错误',
            content: '请在app和小程序端体验录音，Uni官方明确H5不支持getRecorderManager, 详情查看Uni官方文档'
          });
        }
      },
      
      onRecordEnd() {
        try {
          recorderManager.stop();
        } catch (e) {
          console.log(e);
        }
      },
      
      sendImageMessage() {
        uni.chooseImage({
          count: 9,
          success: (res) => {
            console.log(res);
            uni.showLoading({
              title: '发送中...'
            });
            let file = res.tempFiles[0].path
            uni.uploadFile({
              url: config.baseUrl + '/api/v1/uploadUser',
              filePath: file,
              name: 'file',
              header: {
                'Authorization': uni.getStorageSync('token')
              },
              success: (uploadRes) => {
                const now = Date.now();
                const message = {
                  messageId: 'msg' + now,
                  type: 'image',
                  senderId: this.currentCustomer.user_id,
                  senderData: { name: this.currentCustomer.name },
                  timestamp: now,
                  payload: { text: this.text },
                  status: 'success',
                  content: JSON.parse(uploadRes.data).result.imageUrl,
                  create_time: now,
                  content_type: 'image',
                  user_id: this.currentCustomer.id,
                };
                uni.hideLoading()

                this.history.messages.push(message);
                this.scrollToBottom();

                console.log(uploadRes);
              },
              fail: (err) => {
                console.log('上传失败:', err);
                uni.hideLoading();
                
                const now = Date.now();
                const failMessage = {
                  messageId: 'msg' + now,
                  type: 'image',
                  senderId: this.currentCustomer.user_id,
                  senderData: { name: this.currentCustomer.name },
                  timestamp: now,
                  payload: { text: '图片发送失败' },
                  status: 'fail',
                  content: '图片发送失败',
                  create_time: now,
                  content_type: 'text',
                  user_id: this.currentCustomer.id,
                };
                this.history.messages.push(failMessage);
                this.scrollToBottom();
              }
            });
          }
        });
      },
      
      showImageFullScreen(e) {
        let imagesUrl = [config.baseUrl+e.currentTarget.dataset.url];
        uni.previewImage({
          urls: imagesUrl
        });
      },
      
      checkAndReconnectWebSocket() {
        if (!this.ws.isConnected) {
          console.log('WebSocket已断开，重新连接...');
          this.connect();
        } else {
          console.log('WebSocket连接正常，发送测试心跳');
          uni.sendSocketMessage({
            data: 'ping',
            success: () => {
              console.log('连接测试成功');
            },
            fail: (err) => {
              console.log('连接测试失败，重新连接...', err);
              this.ws.isConnected = false;
              this.connect();
            }
          });
        }
      },
      
      handlePageClick() {
        this.otherTypesMessagePanelVisible = false;
      }
    }
  }
</script>

<style>
  page {
    height: 100%;
  }

  .chatInterface {
    height: 100%;
    background-color: #F1F1F1;
    display: flex;
    flex-direction: column;
  }

  .scroll-view {
    padding-left: 20rpx;
    padding-right: 20rpx;
    box-sizing: border-box;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 120rpx;
    background-color: #F1F1F1;
    flex: 1;
  }

  .scroll-view .message-item {
    display: flex;
    margin: 20rpx 0;
  }

  .scroll-view .message-item .message-item-content {
    flex: 1;
    overflow: hidden;
    display: flex;
  }

  .scroll-view .message-item .message-item-content.self {
    overflow: hidden;
    display: flex;
    justify-content: flex-start;
    flex-direction: row-reverse;
  }

  .scroll-view .message-item .avatar {
    width: 80rpx;
    height: 80rpx;
    flex-shrink: 0;
    flex-grow: 0;
  }

  .scroll-view .message-item .avatar image {
    width: 100%;
    height: 100%;
    border-radius: 50%;
  }

  .scroll-view .message-item .accept-message {
    width: 100%;
    text-align: center;
    color: #333333;
    font-size: 34rpx;
  }

  .scroll-view .content {
    font-size: 34rpx;
    line-height: 44rpx;
    margin: 0 20rpx;
    max-width: 520rpx;
    display: flex;
    flex-direction: column;
  }

  .scroll-view .content .staff-name {
    font-size: 34rpx;
    color: #888888;
  }

  .scroll-view .content .message-payload {
    display: flex;
    align-items: center;
  }

  .scroll-view .content .image-content {
    border-radius: 12rpx;
  }

  .scroll-view .content .text-content img {
    width: 50rpx;
    height: 50rpx;
  }

  .scroll-view .content .pending {
    background: url("~@/static/images/pending.gif") no-repeat center;
    background-size: 30rpx;
    width: 30rpx;
    height: 30rpx;
    margin-right: 10rpx;
  }

  .scroll-view .content .send-fail {
    background: url("~@/static/images/failed.png") no-repeat center;
    background-size: 30rpx;
    width: 30rpx;
    height: 30rpx;
    margin-right: 10rpx;
  }

  .action-box {
    display: flex;
    backdrop-filter: blur(0.27rpx);
    width: 100%;
    position: fixed;
    bottom: 0;
    left: 0;
    flex-direction: column;
    background-color: #F1F1F1;
    z-index: 999;
    transition: bottom 0.3s ease;
  }

  .action-box .action-top {
    display: flex;
    align-items: center;
    box-sizing: border-box;
    background: #F6F6F6;
    backdrop-filter: blur(27.1828px);
    border-top: 1px solid #ECECEC;
    padding: 0 20rpx;
  }

  .consult-input {
    flex: 1;
    height: 80rpx;
    padding-left: 20rpx;
    margin: 20rpx;
    margin-left: 0;
    border: none;
    outline: none;
    box-sizing: border-box;
    border-radius: 6px;
    background: #FFFFFF;
    font-size: 34rpx;
  }

  .more {
    width: 62rpx;
    height: 62rpx;
    margin-right: 10rpx;
    display: flex;
  }

  .send-btn-box {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 110rpx;
    height: 60rpx;
    border-radius: 10rpx;
    background: #D02129;
  }

  .send-btn-box .btn {
    color: #FFFFFF;
    font-size: 34rpx;
  }

  .action-box .action-bottom .more-icon {
    display: flex;
    align-items: center;
    flex-direction: column;
    padding: 0 30rpx;
  }

  .action-box .action-bottom .operation-icon {
    width: 60rpx;
    height: 60rpx;
    min-width: 60rpx;
    min-height: 60rpx;
    padding: 25rpx;
    border-radius: 20rpx;
    background: #FFFFFF;
  }
  
  .action-box .action-bottom .operation-title {
    font-size: 34rpx;
    line-height: 50rpx;
    color: #82868E;
  }

  .action-box .action-top .record-input {
    flex: 1;
    width: 480rpx;
    height: 80rpx;
    line-height: 80rpx;
    padding-left: 20rpx;
    margin: 20rpx;
    margin-left: 0;
    border: none;
    outline: none;
    box-sizing: border-box;
    border-radius: 6px;
    background: #cccccc;
    color: #FFFFFF;
    font-size: 34rpx;
    text-align: center;
  }

  .action-bottom {
    height: 300rpx;
    width: 100%;
    padding: 20rpx;
    box-sizing: border-box;
    display: flex;
  }

  .record-loading {
    position: fixed;
    top: 50%;
    left: 50%;
    width: 300rpx;
    height: 300rpx;
    margin: -150rpx -150rpx;
    background: #262628;
    border-radius: 40rpx;
  }

  .time-lag {
    font-size: 34rpx;
    text-align: center;
  }
</style> 